﻿using Microsoft.AspNetCore.Http;
using mozhi.smarterp.Finance.Accounts;
using mozhi.smarterp.Finance.Enums;
using mozhi.smarterp.Finance.Finances.Repository;
using Mozhi.Abp.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;

namespace mozhi.smarterp.Finance.Finances.Services.EndPeriodProcess
{
    public class UndistributedProfitEndPeriodProcessor : EndPeriodProcessorBase<AccountBalance>
    {
        public UndistributedProfitEndPeriodProcessor(EndPeriodProcessItem item, int period, IServiceProvider serviceProvider) : base(item, period, serviceProvider)
        {
        }

        public override async Task<EndPeriodProcessResult> GetProcessResultAsync()
        {
            //需要生成结转损益凭证，并且审核
            await Validate();

            return await base.GetProcessResultAsync();
        }


        protected override async Task<EndPeriodProcessResult> HandleDataAsync()
        {
            //取综合本位币金额
            _data = _data.Where(x => x.CurrencyId == null && x.DimensionGroupValueId == null).ToList();

            ///本年利润科目
            var account4103 = GetAccount(GetEndPeriodProcessSettingAsync("4103")?.CustomAccountCode);

            //未分配利润科目
            var account410407 = GetAccount(GetEndPeriodProcessSettingAsync("410407")?.CustomAccountCode);

            //本年利润
            var incomeAmount = _data.Where(x => x.AccountId == account4103.Id).Sum(x => x.ClosingAmount.ToDecimal());

            var result = new EndPeriodProcessResult(_guidGenerator.Create(), _item.Id, _period, Enums.EndPeriodProcessType.TransferNDP);

            result.Change(true, false, null, incomeAmount, false);

            var items = GetItemResults(result.Id, incomeAmount);

            items.ForEach(item =>
            {
                result.AddItem(item);

            });

            return result;
        }

        protected override async Task<Journal> HandleGenerateJournalAsync()
        {
            _data = _data.Where(x => x.DimensionGroupValueId != null && x.CurrencyId != null).ToList();

            //本年利润科目
            var account4103 = GetAccount(GetEndPeriodProcessSettingAsync("4103")?.CustomAccountCode);


            //未分配利润科目
            var account410407 = GetAccount(GetEndPeriodProcessSettingAsync("410407")?.CustomAccountCode);


            //测算结果
            var measureResult = await GetEndPeriodResultAsync();

            var amount = measureResult.MeasureValue.Value;


            //按照核算维度进行结转

            var journalMananger = _serviceProvider.GetService(typeof(JournalManager)) as JournalManager;

            var defaultJournalNumberPrefix = await GetJournalDefaultNumberPrefix();

            var journal = await journalMananger.Create(_guidGenerator.Create(), defaultJournalNumberPrefix.Id, _period.ToLastDayDateTime());

            var journalItemFor4103 = await GetJournalItemAsync("结转本年未分配利润",amount, account4103, null, 0, AccountDirectionType.Debit);

            var journalItemFor410407 = await GetJournalItemAsync("结转本年未分配利润" , amount, account410407, null , 1 , AccountDirectionType.Credit);

            var journalItems = new List<JournalItem>();

            journalItems.Add(journalItemFor4103);
            journalItems.Add(journalItemFor410407);

            await journalMananger.ChangeItems(journal, journalItems);

            return journal;
        }


        #region
        private async Task Validate()
        {
            var endPeriodProcessItemReposiotry = _serviceProvider.GetService(typeof(IEndPeriodProcessItemRepository)) as IEndPeriodProcessItemRepository;

            var profitLossEndPeriodItem = (await endPeriodProcessItemReposiotry.FindAsync(new Querys.PageQuery() { PageIndex = 1, PageSize = 1000 })).FirstOrDefault(x => x.Index == 8);

            var endPeriodProcessResultReposiotry = _serviceProvider.GetService(typeof(IEndPeriodProcessResultRepository)) as IEndPeriodProcessResultRepository;

            var profitLossEndPeriodItemResult =  (await endPeriodProcessResultReposiotry.FindAsync(new Querys.EndPeriodProcessResultQuery() { Period = _period , ItemId = profitLossEndPeriodItem?.Id })).FirstOrDefault();

            if (profitLossEndPeriodItem == null || profitLossEndPeriodItemResult == null)
                throw new UserFriendlyException("结转损益凭证未生成", "100000");

            if(!profitLossEndPeriodItemResult.JournalId.HasValue)
                throw new UserFriendlyException("结转损益凭证未生成", "100000");

            var journalRepository = _serviceProvider.GetService(typeof(IJournalRepository)) as IJournalRepository;

            var journal = await journalRepository.FindAsync(profitLossEndPeriodItemResult.JournalId.Value);

            if (journal == null || journal.Status == DocumentStatusType.Creation)
                throw new UserFriendlyException("结转损益凭证未审核", "100000");
        }


        private List<EndPeriodProcessResultItem> GetItemResults(Guid resultId , decimal? incomeAmount)
        {
            var result = new List<EndPeriodProcessResultItem>();

            //设置子处理项
            result.Add(new EndPeriodProcessResultItem(_guidGenerator.Create(), resultId, "本年利润合计", incomeAmount?.ToString(), 1, 1, false));

            return result;
        }

        #endregion

    }
}
